package com.smart.community.gateway.utils;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

import org.springframework.util.StringUtils;

import com.smart.community.commons.constants.RequestHeaderConstants;
import com.smart.community.commons.enums.RoleCodeEnum;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * WebFlux环境下的安全工具类
 * 用于在网关中处理用户信息的获取和传递
 * 与Commons模块中的RequestHeaderConstants保持一致
 * 
 * @author Wu.Liang
 * @since 2025-07-01
 * @updated 2025-01-30 - 修复Token解析逻辑，统一请求头常量
 */
@Slf4j
public class WebFluxSecurityUtils {
    
    /**
     * 用户信息传递的请求头常量
     * 与Commons模块中的RequestHeaderConstants保持一致
     */
    public static class Headers {
        public static final String USER_ID = RequestHeaderConstants.USER_ID;
        public static final String USER_NAME = RequestHeaderConstants.USER_NAME;
        public static final String USER_ROLES = RequestHeaderConstants.USER_ROLE;
        public static final String USER_PERMISSIONS = RequestHeaderConstants.USER_PERMISSIONS;
        public static final String USER_TYPE = RequestHeaderConstants.USER_TYPE;
        public static final String COMMUNITY_ID = RequestHeaderConstants.COMMUNITY_ID;
        public static final String PROPERTY_COMPANY_ID = RequestHeaderConstants.PROPERTY_COMPANY_ID;
        public static final String REAL_NAME = RequestHeaderConstants.REAL_NAME;
        public static final String SUPER_ADMIN = RequestHeaderConstants.SUPER_ADMIN;
        public static final String TOKEN = RequestHeaderConstants.TOKEN;
    }
    
    /**
     * 网关用户信息类
     */
    public static class GatewayUserInfo {
        private Long userId;
        private String username;
        private String realName;
        private String token;
        private String userType; // 修改为String类型，符合权威架构文档要求
        private Boolean superAdmin;
        private List<String> roles;
        private List<String> permissions;
        private Long communityId;
        private Long propertyCompanyId;
        
        // Getters and Setters
        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }
        
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        
        public String getRealName() { return realName; }
        public void setRealName(String realName) { this.realName = realName; }
        
        public String getToken() { return token; }
        public void setToken(String token) { this.token = token; }
        
        public String getUserType() { return userType; }
        public void setUserType(String userType) { this.userType = userType; }
        
        public Boolean getSuperAdmin() { return superAdmin; }
        public void setSuperAdmin(Boolean superAdmin) { this.superAdmin = superAdmin; }
        public boolean isSuperAdmin() { return superAdmin != null && superAdmin; }
        
        public List<String> getRoles() { return roles; }
        public void setRoles(List<String> roles) { this.roles = roles; }
        
        public List<String> getPermissions() { return permissions; }
        public void setPermissions(List<String> permissions) { this.permissions = permissions; }
        
        public Long getCommunityId() { return communityId; }
        public void setCommunityId(Long communityId) { this.communityId = communityId; }
        
        public Long getPropertyCompanyId() { return propertyCompanyId; }
        public void setPropertyCompanyId(Long propertyCompanyId) { this.propertyCompanyId = propertyCompanyId; }
    }
    
    /**
     * 验证Token是否有效
     * 简化Token验证逻辑：检查token格式和长度
     * Sa-Token生成的token是UUID格式，长度为36位
     * 
     * @param token Token值
     * @return 是否有效
     */
    public static boolean isValidToken(String token) {
        if (!StringUtils.hasText(token)) {
            log.warn("Token为空，无法获取用户信息");
            return false;
        }
        
        if (token.length() != 36 || !token.matches("[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}")) {
            log.warn("Token格式不正确: {}", token);
            return false;
        }
        
        return true;
    }
    
    /**
     * 构建用户信息请求头
     * 将用户信息转换为请求头键值对，供下游服务使用
     * 检查是否为超级管理员，如果是则注入*:*:*权限
     * 
     * @param userInfo 用户信息
     * @return 请求头键值对数组 [key1, value1, key2, value2, ...]
     */
    public static String[] buildUserHeaders(GatewayUserInfo userInfo) {
        if (userInfo == null) {
            log.warn("用户信息为空，无法构建请求头");
            return new String[0];
        }
        
        try {
            List<String> roles = userInfo.getRoles();
            List<String> permissions = userInfo.getPermissions();
            
            // 检查是否为超级管理员
            boolean isSuperAdmin = false;
            if (roles != null && !roles.isEmpty()) {
                isSuperAdmin = roles.contains(RoleCodeEnum.SUPER_ADMIN.getCode());
            }
            
            // 如果是超级管理员，强制设置权限为*:*:*
            if (isSuperAdmin) {
                // 检测到超级管理员用户，强制设置权限为*:*:* - 已隐藏详细日志
                permissions = Arrays.asList("*:*:*");
            }
            
            // 将角色和权限列表转换为JSON格式字符串
            String rolesStr = roles != null ? JSONUtil.toJsonStr(roles) : "[]";
            String permissionsStr = permissions != null ? JSONUtil.toJsonStr(permissions) : "[]";
            
            String[] headers = new String[]{
                    Headers.USER_ID, String.valueOf(userInfo.getUserId()),
                    Headers.USER_NAME, encodeValue(userInfo.getUsername()),
                    Headers.USER_ROLES, encodeValue(rolesStr),
                    Headers.USER_PERMISSIONS, encodeValue(permissionsStr),
                    Headers.USER_TYPE, String.valueOf(userInfo.getUserType()),
                    Headers.COMMUNITY_ID, userInfo.getCommunityId() != null ? String.valueOf(userInfo.getCommunityId()) : "",
                    Headers.PROPERTY_COMPANY_ID, userInfo.getPropertyCompanyId() != null ? String.valueOf(userInfo.getPropertyCompanyId()) : "",
                    Headers.REAL_NAME, encodeValue(userInfo.getRealName()),
                    Headers.SUPER_ADMIN, String.valueOf(isSuperAdmin),
                    Headers.TOKEN, encodeValue(userInfo.getToken())
            };
            
            // 构建用户信息请求头成功 - 已隐藏详细日志
            
            return headers;
            
        } catch (Exception e) {
            log.error("构建用户信息请求头失败: {}", e.getMessage(), e);
            return new String[0];
        }
    }
    
    /**
     * URL编码工具方法
     * 
     * @param value 需要编码的值
     * @return 编码后的值
     */
    private static String encodeValue(String value) {
        if (!StringUtils.hasText(value)) {
            return "";
        }
        
        try {
            return URLEncoder.encode(value, StandardCharsets.UTF_8.name());
        } catch (Exception e) {
            log.warn("URL编码失败: {}", e.getMessage());
            return value;
        }
    }
} 